package app

import (
	"bytes"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"sync"
	"time"
)

// pathInfo 是一个结构体，用于封装路径的信息
type pathInfo struct {
	path    string      // 路径
	exists  bool        // 是否存在
	isFile  bool        // 是否为文件
	isDir   bool        // 是否为目录
	size    int64       // 文件大小（字节）
	mode    os.FileMode // 文件权限
	modTime time.Time   // 文件修改时间
}

// checkPath 检查给定路径的信息
func checkPath(path string) (pathInfo, error) {
	// 创建一个 PathInfo 结构体
	var info pathInfo

	// 清理路径，确保没有多余的斜杠
	path = filepath.Clean(path)

	// 设置路径
	info.path = path

	// 使用 os.Stat 获取文件状态
	fileInfo, err := os.Stat(path)
	if err != nil {
		if os.IsNotExist(err) {
			// 如果路径不存在, 则直接返回
			info.exists = false
			return info, fmt.Errorf("路径 '%s' 不存在，请检查路径是否正确: %s", path, err)
		} else {
			return info, fmt.Errorf("无法访问路径 '%s': %s", path, err)
		}
	}

	// 路径存在，填充信息
	info.exists = true                // 标记路径存在
	info.isFile = !fileInfo.IsDir()   // 通过取反判断是否为文件，因为 IsDir 返回 false 表示是文件
	info.isDir = fileInfo.IsDir()     // 直接使用 IsDir 方法判断是否为目录
	info.size = fileInfo.Size()       // 获取文件大小
	info.mode = fileInfo.Mode()       // 获取文件权限
	info.modTime = fileInfo.ModTime() // 获取文件的最后修改时间

	// 返回路径信息结构体
	return info, nil
}

// execCmd 执行命令
// cmd: 命令名称
// args: 命令参数
// 返回值: 错误信息
func execCmd(cmd ...string) error {
	// 检查是否为空
	if len(cmd) == 0 {
		return fmt.Errorf("命令不能为空")
	}

	// 根据是否有参数来构建命令
	command := exec.Command("cmd", append([]string{"/q", "/C", cmd[0]}, cmd[1:]...)...)

	// 设置一个缓冲区，用于捕获命令的输出
	var outputBuffer bytes.Buffer
	command.Stdout = &outputBuffer
	command.Stderr = &outputBuffer

	// 设置等待锁
	var w sync.WaitGroup

	// 启动一个 goroutine 来等待命令执行完成
	w.Add(1)
	var result error // 用于存储命令执行的错误信息
	go func() {
		defer w.Done()

		// 执行命令
		startErr := command.Start()
		if startErr != nil {
			result = fmt.Errorf("执行命令 '%s' 失败: %s, 输出: %s", cmd, startErr, outputBuffer.String())
		}
	}()
	w.Wait()

	// 检查命令是否执行成功
	if result != nil {
		return result
	}

	// 成功执行
	return nil
}
